package org.vz;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.jwk.source.RemoteJWKSet;
import com.nimbusds.jose.proc.BadJOSEException;
import com.nimbusds.jose.proc.JWSKeySelector;
import com.nimbusds.jose.proc.JWSVerificationKeySelector;
import com.nimbusds.jose.proc.SecurityContext;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
import com.nimbusds.jwt.proc.DefaultJWTProcessor;
import org.dmfs.httpessentials.client.HttpRequestExecutor;
import org.dmfs.httpessentials.exceptions.ProtocolError;
import org.dmfs.httpessentials.exceptions.ProtocolException;
import org.dmfs.httpessentials.httpurlconnection.HttpUrlConnectionExecutor;
import org.dmfs.oauth2.client.*;
import org.dmfs.oauth2.client.grants.ClientCredentialsGrant;
import org.dmfs.oauth2.client.scope.EmptyScope;
import org.dmfs.rfc3986.encoding.Precoded;
import org.dmfs.rfc3986.uris.LazyUri;
import org.dmfs.rfc5545.Duration;

import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.cert.CertificateException;
import java.text.ParseException;

/**
 * Hello world!
 */
public class Oauth2ClientCredental {
    public static void main(String[] args) throws ProtocolError, ProtocolException, IOException, JOSEException, ParseException, InvalidKeyException, BadJOSEException, CertificateException {
           /*******************io.jsonwebtoken*************/
            /**初始化客户端**/
        HttpRequestExecutor executor = new HttpUrlConnectionExecutor();


        OAuth2AuthorizationProvider provider = new BasicOAuth2AuthorizationProvider(
                URI.create("http://dhis2.cn:31000/connect/authorize"),
                URI.create("http://dhis2.cn:31000/connect/token"),
                new Duration(1, 0, 3600) /* default expiration time in case the server doesn't return any */);

// Create OAuth2 client credentials
       /* OAuth2ClientCredentials credentials = new BasicOAuth2ClientCredentials(
                "ding6f88a1e8f56dc38435c2f4657eb6378f", "4gdPaJfMULp8m5JuJE9mpkHVRBgoj_0sZBWHyKJpsuVOsW8oWib-mW0PKO_bFjU7");*/
        OAuth2ClientCredentials credentials = new BasicOAuth2ClientCredentials(
                "client_test", "9d518cbc1a0746c3b27742c349b27b0a");

        org.dmfs.rfc3986.Uri redirectUrl =  new LazyUri(new Precoded("http://192.168.120.219:2182/hapi-fhir-jpaserver-example"));

// Create OAuth2 client
        OAuth2Client client = new BasicOAuth2Client(
                provider,
                credentials,
                redirectUrl /* Redirect URL */);

        /**初始化客户端**/


        /********用Authorization Code方式*******/
        // Start an interactive Authorization Code Grant
       /* OAuth2InteractiveGrant grant = new AuthorizationCodeGrant(
                client, new BasicScope("scope"));

        // Get the authorization URL and open it in a WebView
        URI authorizationUrl = grant.authorizationUrl();
        System.out.println(authorizationUrl.toString());


        // Open the URL in a WebView and wait for the redirect to the redirect URL
// After the redirect, feed the URL to the grant to retrieve the access token

        OAuth2AccessToken token = grant.withRedirect(redirectUrl).accessToken(executor);*/

    /********用Authorization Code方式*******/


    /*****************用client_credentials方式 ********************/
        OAuth2AccessToken token = new ClientCredentialsGrant(client, new EmptyScope()).accessToken(executor);

        String realToken = token.accessToken().toString();
        System.out.println("获取的token为:\n"+realToken);

    /*****************用client_credential方式 ********************/



/*********************用nimbus-jose-jwt进行签名验证***************/

// Set up a JWT processor to parse the tokens and then check their signature
// and validity time window (bounded by the "iat", "nbf" and "exp" claims)
        ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor();

// The public RSA keys to validate the signatures will be sourced from the
// OAuth 2.0 server's JWK set, published at a well-known URL. The RemoteJWKSet
// object caches the retrieved keys to speed up subsequent look-ups and can
// also gracefully handle key-rollover
        JWKSource keySource = new RemoteJWKSet(new URL("http://dhis2.cn:31000/.well-known/openid-configuration/jwks"));//获取public_key


        // The expected JWS algorithm of the access tokens (agreed out-of-band)
        JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256;

// Configure the JWT processor with a key selector to feed matching public
// RSA keys sourced from the JWK set URL
        JWSKeySelector keySelector = new JWSVerificationKeySelector(expectedJWSAlg, keySource);
        jwtProcessor.setJWSKeySelector(keySelector);

        // Process the token
        SecurityContext ctx = null; // optional context parameter, not required here
        JWTClaimsSet claimsSet = jwtProcessor.process(realToken, ctx);
// Print out the token claims set
        System.out.println(claimsSet.toJSONObject());
		 System.out.println(claimsSet.toJSONObject().get("scope"));

        /*********************用nimbus-jose-jwt进行签名验证***************/









    }

}
